今天是機派X系列文章的第四天。
昨天介紹了 Bash 的基本概念,大家都熟悉了嗎?
本篇將介紹 Linux 的檔案系統,並透過 Bash 來操作檔案系統。
本篇大綱:
前一篇文章中有提到,shell 是我們(也就是使用者)與 Ubuntu 間的橋樑,透過 shell 輸入指令就能操作電腦!因此,接著我們會介紹一些常用的指令,熟悉這些指令後,使用 Ubuntu 將會變得輕鬆又自在。
我將要介紹的指令依用途分為:
這些類別中的指令彼此可以互相搭配使用,用以構成我們想要電腦做的事!
因此在介紹以上指令後,會有一篇文章提供幾個指令使用的範例,這些範例會將不同指令結合並寫成腳本,用以完成一些特定工作。
在介紹檔案系統相關的指令前,先簡單說一下什麼是檔案系統(File System , FS)。檔案系統能夠將硬體裝置中的資料彙整成井然有序的樣子(例如:樹狀結構)以便使用者操作。硬碟(Disk)、磁區(Partition)、資料區塊(Block)等概念,透過檔案系統的包裝形成樹狀結構,使用者只要透過樹狀結構所形成的檔案路徑,即可存取檔案。舉例來說,當你開啟一個 Word 檔並進行編輯時,你只需要知道檔案的儲存路徑(例如 D:\Documents\report.docx)就可以完成相關操作,而無須知道檔案具體在硬碟中是如何被儲存的。
Linux 的檔案系統與 Windows 不同,又之後的 Bash 指令介紹會涉及檔案操作,因此在介紹 Bash 中常用的指令前,必須要介紹 Linux 的檔案系統。
常見的 Windows 系統是以磁區(Partition / Volume)做為檔案系統的基本單位。由於一台電腦中可能存在多個不同的磁區,因此一台電腦中的檔案結構可能是由多個彼此獨立的樹狀結構所構成。以下圖來說,磁碟 0、磁區 1(Disk 0, Partition 1)被掛載上了磁區代號 C,以 C: 為樹狀結構的根(root)就可以存取底下的檔案與資料夾。而光碟機則是被掛載上了磁區代號 E,以 E: 為樹狀結構的根,又可以得到另一個樹狀圖。
而 Linux 的檔案系統則是僅由一個樹狀結構所形成。如下圖所示,樹狀圖中每個圓圈都是一個節點,也是一個目錄(Directory),而灰色線條則是連接父目錄與子目錄(樹狀圖的概念中可以稱為父節點與子節點),這張圖其實並不完整,沒有把每個節點都繪出,之後實際操作指令時會把完整結構呈現出來。樹狀圖中的的根(root)就是 Linux 檔案系統的頂端,我們稱它為根目錄(root directory),寫成路徑時會寫成 / 。
Note :
別忘了,在 Linux 中,資料夾(Folder)又稱為目錄(Directory)。
而路徑表示中,Windows 採用反斜線 \,Linux 採用正斜線 / 。
在根目錄底下,會有許多目錄,用於儲存不同東西。我們只介紹之後常用到的幾個,至於其他部份可以參考 鳥哥的 Linux 教學 。
目錄路徑 | 用途 | 例子 |
---|---|---|
/dev | 目錄中的檔案直接連接至各設備,例如:硬碟、網路攝影機等。對其下的檔案操作,形同於直接操作對應的設備。 | 如果今天你在 RPi 上插入了一個隨身碟,通常會被掛載於 /dev/sda 。直接對 /dev/sda 操作就等同操作隨身碟中的資料。 |
/home | 在 Linux 系統中,每個使用者通常都會有一個家目錄(Home Directory),其功能類似於 Windows 中的 C:\Users\%USERNAME% ,可用於儲存各個使用者的資料。通常,使用者的家目錄會位於 /home 目錄底下。 | 例如使用者 ubuntu 的家目錄通常位於 /home/ubuntu ,在這個目錄中使用者 ubuntu 可以儲存自己的私人資料。 |
/etc | 包含各項系統設定檔。 | 例如之後會用到的 ssh server 的設定檔就位於這裡。 |
/var | 包含系統運作時所產生的檔案。 | 例如:系統日誌(Log)、錯誤發生日誌(Error Log)、快取(Cache)等。 |
/tmp | 用於暫時儲存某些檔案或目錄。 | 例如:程式執行時,臨時需要一個資料夾暫存資料,/tmp 就是個好地方。可搭配 mktmp 指令來使用。 |
Note :
登入 Shell 後,通常預設的工作目錄都會是自己的家目錄(Home Directory)。例如前一天有提到,使用者 ubuntu 登入後,預設的工作目錄是 /home/ubuntu 也就是 ubuntu 的家目錄。另外在 Bash 中使用者的家目錄又可以被簡寫為 ~ ,所以如果是以使用者 labuser 登入的話,~ 其實就等同 /home/labuser 。
接下來要開始介紹指令(CMD)了,並實際操作這些指令。不同的 Shell 其支援的指令也不相同,本系列文章會以 Bash 為主做介紹。不過即使你使用了其他的 Shell 也沒關係,因為很多基本指令是共通的。
Note :
以下僅會帶過常用的指令以及常用的用法,若要查看完整的指令說明,請詳閱指令使用手冊或善用網路資源。另外,部份範例可能會讓你覺得難以理解,建議可以查詢相關指令的說明書後再看看,可能會有意想不到的發現,畢竟教學不是我一個人的事,希望讀者也能自主思考、動手去做,尤其是在實做這個區塊更是如此,如果用盡各種方法還是無法理解,歡迎在文章下方留言,讓我或邦幫忙上的大家幫你一把。
首先第一個是 echo,如果你學過其他程式語言,你應該會知道 print() 或 System.out.print() 等函式。echo 的功用也是如此,echo 用於將資料輸出至螢幕上。
以下是 echo 的用法:
echo [OPTION]...... [MESSAGE]......
MESSAGE 就是你要印在螢幕上的訊息,而 [] 代表其內的東西可有可無,依照你的需求而定。
例如:我們希望輸出 Hello,我們可以這樣下指令:
echo Hello
echo 輸出訊息時,會自動在結尾添加一個換行,因此輸出看起來會像這樣:
ubuntu@ubuntu:~$ echo Hello
Hello
ubuntu@ubuntu:~$
如果不給 MESSAGE 內容的話,只會輸出 echo 自動幫你加的換行。
ubuntu@ubuntu:~$ echo
ubuntu@ubuntu:~$
[MESSAGE] 後方的 ...... 代表 [MESSAGE] 可以不只一個!
例如:
ubuntu@ubuntu:~$ echo Hello World
Hello World
ubuntu@ubuntu:~$
而 OPTION 則是 echo 的引數要放的位置。
如果不想要結尾自動添加的換行,可以為 echo 增加一個引數 -n 。
ubuntu@ubuntu:~$ echo -n Hello
Helloubuntu@ubuntu:~$
可以把引數想成修飾的功能,我要執行 echo 指令,但是又希望 echo 能根據我的需求客製化行為,因此加上了引數來做調控。為什麼叫做引數呢?因為他能夠引導一些「需求」給 echo,讓 echo 改變行為。如果有學過程式的話,這邊提到的引數其實跟函式(function)的引數是一樣的意思,只是形式看起來不一樣而已。
可以觀察到 OPTION 也有 [] 包起來,所以沒有給 OPTION 也沒關係,所以前幾個範例沒給 OPTION 還是能正常執行。OPTION 後方也有 ...... ,所以引數也可以給很多個。
Note :
使用 echo 輸出訊息的時候,建議將訊息以引號包起來,以避免發生問題。
例如: echo 'Hello'
使用單引號 ' 或雙引號 " 其實意義不同,不過在這邊你可以先混用,之後提到變數時候會再介紹。
請將樹莓派開機並登入 Ubuntu,等到看到熟悉的 $ 符號出現就可以開始打指令囉。
你可以嘗試以下幾個指令:
echo Hello World
echo Hello
echo -n Hello
echo 'Hello World'
echo 'Hello\nWorld'
echo -e 'Hello\nWorld'
echo -e 'Hello\nWorld\n'
在程式中 \n 代表換行,可以觀察到 echo 'Hello\nWorld' 並沒有作用 。
ubuntu@ubuntu:~$ echo 'Hello\nWorld'
Hello\nWorld
ubuntu@ubuntu:~$
原因是因為 echo 預設不會解讀跳脫字元 \n ,所以 \n 會被直接印出。只要加上 -e 引數就可以讓 echo 解讀跳脫字元了。
ubuntu@ubuntu:~$ echo -e 'Hello\nWorld'
Hello
World
ubuntu@ubuntu:~$
如同前面提到的,echo 允許我們有多個引數,例如:
ubuntu@ubuntu:~$ echo -e -n 'Hello\nWorld'
Hello
Worldubuntu@ubuntu:~$
因為 -e 所以 Hello 和 World 之間有換行,而因為有 -n 所以 World 後方沒有自動加換行。
再來看看這些例子吧:
echo 'Happy Father'\''s Day'
echo "Happy Father"\'"s Day"
echo "Happy Father's Day"
你可以透過 touch 來建立一個純文字文件。
以下是 touch 的使用方式。
touch [OPTION]...... FILENAME......
可以觀察到 FILENAME 沒有 [] 包住,代表檔名是一定要給的。
ubuntu@ubuntu:~$ touch
touch: missing file operand
Try 'touch --help' for more information.
ubuntu@ubuntu:~$
建立檔案時,如果檔名有空白,要用引號包起來,不然會被以為是兩個文件的檔名。
touch Hello World
touch 'Hello World'
也許你會覺得奇怪,教你使用 touch 建立檔案,但是卻沒教你如何看檔案是否成功建立,也不知道目前有什麼檔案。
接下來教你使用 ls 來列出特定檔案與目錄中的內容。
ls 的使用方式如下:
ls [OPTION]...... [FILE]......
FILE 如果是某個檔案的檔名,則 ls 會列出該檔案的相關資訊;FILE 如果是個目錄,則 ls 會列出目錄中的檔案和資料夾;FILE 如果省略不寫,則會顯示當前工作目錄下的檔案。FILE 可以使用相對路徑來寫,也以使用絕對路徑。如果是使用相對路徑,則其基準就是工作目錄。另外,如果路徑中有空白,應該將路徑以引號包住!
Note :
別忘記了,之前有介紹過工作目錄(Working Directory),簡單來說工作目錄就是「你下指令時,所在的目錄位置」。當我們下的指令有需要操作檔案時,恰巧檔案路徑又使用相對路徑,此時工作目錄就會顯的很重要。如果忘記相關說明,請移駕至昨天的文章看看。
舉例來說,這樣可以顯示當前工作目錄的檔案與目錄:
ls
而引數 -l 可以將檔案與目錄的詳細資料列出。在 Linux 中,檔案或目錄的檔名若以 . 開頭會被視為隱藏檔案,ls 預設不會顯示,加上引數 -a 可以將隱藏檔也一併列出。
你可以試試看以下幾個範例:
ls .
ls ..
ls ~
ls -l ~
ls -l -a ~
ls -l /var/log
透過 cat 你可以查看純文字檔案的內容。
以下是用法:
cat [OPTION]...... [FILE]......
FILE 就是要查看的檔案路徑,跟 ls 一樣,FILE 可以是絕對路徑或相對路徑。之後很多指令會用到檔案操作,檔案路徑的寫法也相同,之後便不會再多提。
你可以嘗試以下指令:
cat /etc/passwd
cat /var/log/syslog
看完這篇文章後,你可以思考這個:
echo -e 'Apple\nBanana\nGrapes' > part1.txt
echo -e 'Papaya\nPineapple' > part2.txt
cat part1.txt part2.txt > fruit.txt
rm part1.txt part2.txt
cat /var/log/syslog 覺得很麻煩嗎?
可曾想過將工作目錄換到 /var/log ,這樣就可以直接執行 cat syslog ?
透過 cd 可以切換工作目錄。以下是 cd 的用法,dir 就是新的工作目錄的位置,若是省略 dir 就會直接切換到家目錄。
cd [DIR]
你可以嘗試以下幾個例子,並搭配 ls 使用:
cd /var/log
cd ..
cd
cd ./..
透過 > 可以將資料重新定向,> 的左方是資料, > 的右方是資料要輸出至的檔案名稱。
例如,以下指令會在螢幕上輸出 Hello World,但是透過 > 可以將資料輸出到指定檔案中。
echo 'Hello World'
例如,將資料輸出至檔案 kkk.txt 中。
echo 'Hello King of the World' > kkk.txt
另外,你可以嘗試以下指令:
echo 'Hello Queen' >> kkk.txt
你可以透過 mkdir 與 rmdir 來建立與刪除目錄,請參考以下用法。
mkdir [OPTION]...... [DIR]......
rmdir [OPTION]...... [DIR]......
DIR 就是要建立或刪除的目錄的路徑。
可以嘗試以下幾個例子並搭配 ls 來觀察指令執行結果:
mkdir 123/456/789
mkdir -p 123/456/789
mkdir 123
rmdir 123/456
rmdir 123/456/789
rmdir 123/456
rmdir 123
rmdir 只能用來刪除空目錄,若要刪除非空目錄或檔案,請使用 rm。
rm [OPTION]...... [FILE]......
可以嘗試以下例子並搭配 ls 來觀察指令執行結果:
mkdir abc
touch abc/hello
rm abc
rm -r abc
mv 可以用於移動檔案或目錄,可以想成 move 的縮寫。
以下是用法,SOURCE 是來源路徑,可以是檔案或目錄,DEST 是目標路徑。
mv SOURCE DEST
可以嘗試以下例子並搭配 ls 來觀察指令執行結果:
touch hello
mv hello world
mkdir 123 456
mv 456 123/456
mkdir foo
touch data
mv data foo
mkdir a b
mv b a
mkdir i j
touch j/data
mv j i/k
cp 原文是 copy,所以很明顯 cp 指令的用途是複製檔案或目錄。
cp [OPTION] SOURCE DEST
直接來幾個範例吧!
echo 'Hello World' > a
cp a A
mkdir bar
touch bar/apple bar/banana
cp bar foo
cp -r bar foo
以上一些指令大家還 ok 嗎?
你會知道怎麼用這些指令是因為我有說明,那你是否好奇我怎麼知道這些指令呢?
指令如此繁多,用法各異,參數也各自自成一國,又該如何記住呢?
其實掌握兩個技巧就可以了:
因為常用到的指令自然會記得,以上面那些例子來說,常常會用到 ls ,我想 ls 的用法要你現在忘掉也不容易。常用的東西想忘也忘不掉,當然也就不用背,這就是熟練就好的意思。
(圖源傳送門:此圖源於網路,但是我找不到來源,因此版權方若看到本圖請跟我聯絡)
那不常用的東西呢?因為不常用,所以忘記在所難免,可以透過網路查詢或看使用說明來解決。如果某個指令或特定參數因不常用而忘記,那也無須逼迫自己硬記,要用到的時候再查詢就好,反正也不常用,所以偶爾查一下不會浪費很多時間。
查詢時要有效率,才不會浪費時間。
而我又是如何知道這些指令以及使用方式的呢?
Answer:man
man 也是一條指令,man 的原文是 manual 也就是使用手冊,man 就是用來查詢使用手冊的指令。
man [OPTION] [SECTION] [CMD]
CMD 就是你要查詢的指令名稱,SECTION 是章節編號。
你可以嘗試以下幾個例子:
man ls
man rmdir
man man
man passwd
man 5 passwd
透過 man 你可以快速了解一個指令的用途、用法等資訊,甚至還能透過 man 來查詢 man 的用法。
以後忘記指令或是看到陌生指令,不妨使用 man 來查詢看看吧!
在程式的世界中,有時會在程式或指令旁標示一些給人看的文字,用於說明某程式的功用或是呈現作者相關資訊,這些文字不是程式或指令,因此電腦看到時會略過不管,我們稱它為註解(comment)。
在 Bash 中,只要是以 # 開頭的那行,整行都會被視為註解。
例如:
# Print Hello
因為以 # 開頭,所以會被視為註解,# 後面的內容是給人看的,電腦會略過不看。
註解在目前看似無用,但在之後寫腳本的時候卻會派上用場!
最後要介紹的是如何將系統關機或重新開機,這部份雖然不屬於檔案系統的操作,但是我實在找不到其他適合的地方來擺放這段,所以先放這裡吧!
# 關機
poweroff
# 重新開機
reboot
# 登出當前的使用者
exit
Note :
其實也可以使用 shutdown 指令來操作,只是需要熟悉一下參數使用。相對參數的變換來說,也許直觀的英文單字所組成的指令更能迅速烙印在你的腦海中,因此上面才會介紹那些指令。
如果對於文章內容有建議、糾錯或圖源標示不正確的問題,歡迎參考 [機派X] Day 1 嘗試與文章作者聯絡。
想看更多本系列的文章,請連結至 [機派X] Day 1 查看大綱。